package iharbor2

import (
	"bytes"
	"context"
	"errors"
	"github.com/rclone/rclone/backend/iharbor2/api"
	"github.com/rclone/rclone/fs"
	"net/url"
	"strconv"
)

func (f *Fs) v1UploadFile(ctx context.Context, o *Object, k []byte, off, chunkS, part int64, name, reset string) error {
	fs.Debugf(o, "Upload : sending chunk %d length %d", part, len(k))
	bucket, bucketPath := o.split()
	body, contentType, err := f.BufferWirteReader(ctx, bytes.NewBuffer(k), off, chunkS, name, o)
	if err != nil {
		fs.Debugf(o, "Upload Error : There is an error in the cache : %v", err)
		return err
	}
	lengsize := int64(body.Len())
	Path := "/api/" + f.opt.Version + "/obj/" + bucket + "/" + bucketPath + "/"
	ExtraHeaders := map[string]string{
		//"Authorization": "Token " + f.info.Token,
		"Content-Type": contentType,
	}

	opts := f.HandlerAccesskeyHeader("POST", Path, 3600, url.Values{"reset": {reset}}, &lengsize,
		ExtraHeaders, body)

	//opts := rest.Opts{
	//	Method:     "POST",
	//	RootURL:    f.opt.Endpoint + "/api/" + f.opt.Version + "/obj/",
	//	Path:       bucket + "/" + bucketPath + "/",
	//	Body:       body,
	//	Parameters: url.Values{"reset": {reset}},
	//	ExtraHeaders: map[string]string{
	//		//"Authorization": "Token " + f.info.Token,
	//		"Content-Type": contentType,
	//	},
	//	ContentLength: &lengsize,
	//}
	var response api.UploadPartResponse
	count := 9 //重传次数
	err = o.fs.pacer.CallNoRetry(func() (bool, error) {
		resp, err := f.srv.CallJSON(ctx, &opts, nil, &response)
		//if resp != nil {
		//	fmt.Println("第 ", part, "块, 响应 ", response.Created, response.ChunkOffset, resp.StatusCode)
		//} else {
		//	fmt.Println(" resp 为 nill 第 ", part, "块, 响应 ", response.Created, response.ChunkOffset)
		//}
		retry, err := f.shouldRetry(ctx, resp, err)
		if err != nil {
			fs.Debugf(o, "Upload Error: sending chunk %d : %#v", part, err)
		}
		if retry {
		}

		return false, err
	})
	// 客户端发送的请求 服务端没有处理 ，但客户端没有报错
	if err != nil || response.ChunkOffset == 0 && part != 0 {
		for i := 1; i <= count; i++ {
			err = f.v1UploadFile2(ctx, o, k, off, chunkS, part, name, reset, i)
			if err == nil {
				return nil
			}

		}
		err = errors.New(o.Name + "上传失败，err: " + err.Error())
	} else {
		fs.Debugf(o, "Upload Success : Done sending chunk %d", part)
	}
	return err
}

func (f *Fs) v1UploadFile2(ctx context.Context, o *Object, k []byte, off, chunkS, part int64, name, reset string, count int) error {
	fs.Debugf(o, "Retransmission (%d) : sending chunk %d length %d", count, part, len(k))

	bucket, bucketPath := o.split()
	body, contentType, err := f.BufferWirteReader(ctx, bytes.NewReader(k), off, chunkS, name, o)
	if err != nil {
		fs.Debugf(o, "Retransmission (%d) Error ：There is an error in the cache : %v", count, err)
		return err
	}
	lengsize := int64(body.Len())
	Path := "/api/" + f.opt.Version + "/obj/" + bucket + "/" + bucketPath + "/"
	ExtraHeaders := map[string]string{
		//"Authorization": "Token " + f.info.Token,
		"Content-Type": contentType,
	}
	opts := f.HandlerAccesskeyHeader("POST", Path, 3600, url.Values{"reset": {reset}}, &lengsize, ExtraHeaders, body)

	//opts := rest.Opts{
	//	Method:     "POST",
	//	RootURL:    f.opt.Endpoint + "/api/" + f.opt.Version + "/obj/",
	//	Path:       bucket + "/" + bucketPath + "/",
	//	Body:       body,
	//	Parameters: url.Values{"reset": {reset}},
	//	ExtraHeaders: map[string]string{
	//		//"Authorization": "Token " + f.info.Token,
	//		"Content-Type": contentType,
	//	},
	//	ContentLength: &lengsize,
	//}
	var response api.UploadPartResponse

	err = o.fs.pacer.CallNoRetry(func() (bool, error) {
		resp, err := f.srv.CallJSON(ctx, &opts, nil, &response)
		//if resp != nil {
		//	fmt.Println("重传第 ", part, "块, 响应 ", response.Created, response.ChunkOffset, resp.StatusCode)
		//} else {
		//	fmt.Println(" resp 为 nill 重传第 ", part, "块, 响应 ", response.Created, response.ChunkOffset)
		//}
		retry, err := f.shouldRetry(ctx, resp, err)
		if err != nil {
			fs.Debugf(o, "Retransmission (%d) Error: sending chunk %d : %#v", count, part, err)
		}
		if retry {
		}
		return false, err
	})
	if response.ChunkOffset == 0 && part != 0 {
		return errors.New(strconv.FormatInt(part, 10) + "块重新上传失败，等待重新上传...")
	}
	if err == nil {
		fs.Debugf(o, "Retransmission (%d) Success: Done sending chunk %d", count, part)
	}
	return err
}
